using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Input.Touch;

namespace HOPE {
	public static class VirtualThumbsticks {
		#region Fields

		// the distance in screen pixels that represents a thumbstick value of 1f.
		private const float maxThumbstickDistance = 60f;

		// the current positions of the physical touches
		private static Vector2 leftPosition;
		private static Vector2 rightPosition;

		// the IDs of the touches we are tracking for the thumbsticks
		private static int leftId = -1;
		private static int rightId = -1;

		/// <summary>
		/// Gets the center position of the left thumbstick.
		/// </summary>
		public static Vector2? LeftThumbstickCenter { get; private set; }

		/// <summary>
		/// Gets the center position of the right thumbstick.
		/// </summary>
		public static Vector2? RightThumbstickCenter { get; private set; }

		#endregion

		/// <summary>
		/// Gets the value of the left thumbstick.
		/// </summary>
		public static Vector2 LeftThumbstick {
			get {
				// if there is no left thumbstick center, return a value of (0, 0)
				if (!LeftThumbstickCenter.HasValue)
					return Vector2.Zero;

				// calculate the scaled vector from the touch position to the center,
				// scaled by the maximum thumbstick distance
				Vector2 l = (leftPosition - LeftThumbstickCenter.Value) / maxThumbstickDistance;

				// if the length is more than 1, normalize the vector
				if (l.LengthSquared() > 1f)
					l.Normalize();

				return l;
			}
		}

		/// <summary>
		/// Gets the value of the right thumbstick.
		/// </summary>
		public static Vector2 RightThumbstick {
			get {
				// if there is no left thumbstick center, return a value of (0, 0)
				if (!RightThumbstickCenter.HasValue)
					return Vector2.Zero;

				// calculate the scaled vector from the touch position to the center,
				// scaled by the maximum thumbstick distance
				Vector2 r = (rightPosition - RightThumbstickCenter.Value) / maxThumbstickDistance;

				// if the length is more than 1, normalize the vector
				if (r.LengthSquared() > 1f)
					r.Normalize();

				return r;

			}
		}

		/// <summary>
		/// Updates the virtual thumbsticks based on current touch state. This must be called every frame.
		/// </summary>
		public static void Update () {
			TouchLocation? leftTouch = null, rightTouch = null;
			TouchCollection touches = TouchPanel.GetState();

			// Examine all the touches to convert them to virtual dpad positions. Note that the 'touches'
			// collection is the set of all touches at this instant, not a sequence of events. The only
			// sequential information we have access to is the previous location for of each touch.
			foreach (var touch in touches) {
				if (touch.Id == leftId) {
					// This is a motion of a left-stick touch that we're already tracking
					leftTouch = touch;
					continue;
				}

				if (touch.Id == rightId) {
					// This is a motion of a right-stick touch that we're already tracking
					rightTouch = touch;
					continue;
				}

				// We're didn't continue an existing thumbstick gesture; see if we can start a new one.
				//
				// We'll use the previous touch position if possible, to get as close as possible to where
				// the gesture actually began.
				TouchLocation earliestTouch;
				if (!touch.TryGetPreviousLocation(out earliestTouch))
					earliestTouch = touch;

				if (leftId == -1) {
					// if we are not currently tracking a left thumbstick and this touch is on the left
					// half of the screen, start tracking this touch as our left stick
					if (earliestTouch.Position.X < 123 && earliestTouch.Position.X>55/*TouchPanel.DisplayWidth / 2*/
						&&earliestTouch.Position.Y<(369+68) &&earliestTouch.Position.Y>369
						) {
						leftTouch = earliestTouch;
						continue;
					}
				}

				if (rightId == -1) {
					// if we are not currently tracking a right thumbstick and this touch is on the right
					// half of the screen, start tracking this touch as our right stick
					if (earliestTouch.Position.X >= TouchPanel.DisplayWidth / 2) {
						rightTouch = earliestTouch;
						continue;
					}
				}
			}

			// if we have a left touch
			if (leftTouch.HasValue) {
				// if we have no center, this position is our center
				if (!LeftThumbstickCenter.HasValue)
					LeftThumbstickCenter = leftTouch.Value.Position;

				// save the position of the touch
				leftPosition = leftTouch.Value.Position;

				// save the ID of the touch
				leftId = leftTouch.Value.Id;
			}
			else {
				// otherwise reset our values to not track any touches
				// for the left thumbstick
				LeftThumbstickCenter = null;
				leftId = -1;
			}

			// if we have a right touch
			if (rightTouch.HasValue) {
				// if we have no center, this position is our center
				if (!RightThumbstickCenter.HasValue)
					RightThumbstickCenter = rightTouch.Value.Position;

				// save the position of the touch
				rightPosition = rightTouch.Value.Position;

				// save the ID of the touch
				rightId = rightTouch.Value.Id;
			}
			else {
				// otherwise reset our values to not track any touches
				// for the right thumbstick
				RightThumbstickCenter = null;
				rightId = -1;
			}
		}
	}
}
